<template>
  <el-card class="box-card">
    <!-- form校验表单 -->
    <el-form ref="sku" :model="sku" :rules="rules" label-width="80px">
      <!-- SPU名称 -->
      <el-form-item label="SPU名称">
        <span>{{ spu.spuName }}</span>
      </el-form-item>
      <!-- SKU名称 -->
      <el-form-item prop="skuName" label="SKU名称">
        <el-input v-model="sku.skuName" placeholder="请输入SKU名称" />
      </el-form-item>
      <!-- 价格 -->
      <el-form-item prop="price" label="价格">
        <el-input-number
          v-model="sku.price"
          controls-position="right"
          :min="0"
          @change="handleChange"
        />
      </el-form-item>
      <!-- 重量 -->
      <el-form-item prop="weight" label="重量">
        <el-input-number
          v-model="sku.weight"
          controls-position="right"
          :min="0"
          @change="handleChange"
        />
      </el-form-item>
      <!-- SKU描述 -->
      <el-form-item prop="skuDesc" label="SKU描述">
        <el-input
          v-model="sku.skuDesc"
          type="textarea"
          placeholder="请输入SKU描述"
          :rows="3"
        />
      </el-form-item>
      <!-- 平台属性 -->
      <el-form-item prop="skuAttrValueList" label="平台属性">
        <!-- 响应式布局，一行row分成24列，col设置1~24进行列数分配
          xs	<768px 响应式栅格数或者栅格属性对象
          sm	≥768px 响应式栅格数或者栅格属性对象
          md	≥992px 响应式栅格数或者栅格属性对象
          lg	≥1200px 响应式栅格数或者栅格属性对象
          xl	≥1920px 响应式栅格数或者栅格属性对象
         -->
        <el-row>
          <el-col
            v-for="(attrInfo, index) in attrInfoList"
            :key="attrInfo.id"
            :xs="24"
            :sm="12"
            :md="8"
            :lg="6"
            :xl="3"
            class="spu-col"
          >
            <el-form-item :label="attrInfo.attrName">
              <el-select
                v-model="sku.skuAttrValueList[index]"
                placeholder="请选择平台属性值"
                @visible-change="handleAttrVisibleChange"
              >
                <el-option
                  v-for="attrValue in attrInfo.attrValueList"
                  :key="attrValue.id"
                  :label="attrValue.valueName"
                  :value="
                    `${attrInfo.id}:${attrInfo.attrName}:${attrValue.id}:${attrValue.valueName}`
                  "
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form-item>
      <!-- 销售属性 -->
      <el-form-item prop="skuSaleAttrValueList" label="销售属性">
        <el-row>
          <el-col
            v-for="(spuSaleAttr, index) in spuSaleAttrList"
            :key="spuSaleAttr.id"
            :xs="24"
            :sm="12"
            :md="8"
            :lg="6"
            :xl="3"
            class="spu-col"
          >
            <el-form-item :label="spuSaleAttr.saleAttrName">
              <el-select
                v-model="sku.skuSaleAttrValueList[index]"
                placeholder="请选择销售属性值"
                @visible-change="handleSaleAttrVisibleChange"
              >
                <el-option
                  v-for="spuSaleAttrValue in spuSaleAttr.spuSaleAttrValueList"
                  :key="spuSaleAttrValue.id"
                  :label="spuSaleAttrValue.saleAttrValueName"
                  :value="
                    `${spuSaleAttr.id}:${spuSaleAttr.saleAttrName}:${spuSaleAttrValue.id}:${spuSaleAttrValue.saleAttrValueName}`
                  "
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form-item>
      <!-- SKU图片 -->
      <el-form-item prop="skuImageList" label="SKU图片">
        <el-table
          ref="multipleTable"
          :data="spuImageList"
          style="width: 100%"
          border
          @selection-change="handleSelectionChange"
        >
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column label="图片" align="center">
            <template v-slot="{ row }">
              <!--  eslint-disable-next-line -->
              <img class="save-sku-img" :src="row.imgUrl" :alt="row.imgName" />
            </template>
          </el-table-column>
          <el-table-column prop="imgName" label="名称" align="center" />
          <el-table-column v-slot="{ row }" label="操作" align="center">
            <el-button
              v-if="row.isDefault === '0'"
              type="primary"
              size="mini"
              @click="handleSetDefault(row)"
            >
              设置默认图片
            </el-button>
            <el-button v-else type="success" size="mini" disabled>
              默认图片
            </el-button>
          </el-table-column>
        </el-table>
      </el-form-item>
      <!-- 确定和取消按钮 -->
      <el-form-item>
        <el-button type="primary" @click="handleSaveSku">确定</el-button>
        <el-button @click="$emit('isShow', 1)">取消</el-button>
      </el-form-item>
    </el-form>
  </el-card>
</template>

<script>
import { mapState } from 'vuex'

export default {
  name: 'SaveSku',
  props: {
    // 接收的spu数据
    spu: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    // 自定义校验规则
    const priceValidator = (rule, value, callback) => {
      if (value === 0) {
        callback('请设置价格')
      } else {
        callback()
      }
    }
    const weightValidator = (rule, value, callback) => {
      if (value === 0) {
        callback('请设置重量')
      }
      callback()
    }
    const skuAttrValueListValidator = (rule, value, callback) => {
      if (!value.length) {
        callback('请至少选择一个平台属性')
      }
      callback()
    }
    const skuSaleAttrValueListValidator = (rule, value, callback) => {
      if (!value.length) {
        callback('请至少选择一个销售属性')
      }
      callback()
    }
    const skuImageListValidator = (rule, value, callback) => {
      if (!value.length) {
        callback('请至少选择一张图片')
      }
      if (value.every(item => item.isDefault === '0')) {
        callback('必须选择并添加一张默认图片')
      }
      callback()
    }
    return {
      // 平台属性
      attrInfoList: [],
      // SKU图片
      spuImageList: [],
      // 销售属性
      spuSaleAttrList: [],
      // sku属性
      sku: {
        // SKU名称
        skuName: '',
        // 价格
        price: 0,
        // 重量
        weight: '',
        // SKU描述
        skuDesc: '',
        // 平台属性
        skuAttrValueList: [
          // {
          //   attrId: "",
          //   attrName: "",
          //   valueId: "",
          //   valueName: ""
          // }
        ],
        // 销售属性
        skuSaleAttrValueList: [
          // {
          //   saleAttrId: "",
          //   saleAttrName: "",
          //   saleAttrValueId: "",
          //   saleAttrValueName: "",
          // }
        ],
        // SKU图片
        skuImageList: [
          // {
          //   spuImgId: ''
          //   imgName: "",
          //   imgUrl: "",
          //   isDefault: "0",
          // }
        ]

        // category3Id: 0,
        // isSale: 0,
        // skuDefaultImg: "",
        // spuId: "",
      },
      // 校验规则
      rules: {
        skuName: [
          { required: true, message: '请输入SKU名称', trigger: 'blur' }
        ],
        // 价格
        price: [{ required: true, validator: priceValidator }],
        // 重量
        weight: [{ required: true, validator: weightValidator }],
        // SKU描述
        skuDesc: [
          { required: true, message: '请输入SKU描述', trigger: 'blur' }
        ],
        // 平台属性
        skuAttrValueList: [
          { required: true, validator: skuAttrValueListValidator }
        ],
        // 销售属性
        skuSaleAttrValueList: [
          { required: true, validator: skuSaleAttrValueListValidator }
        ],
        // SKU图片
        skuImageList: [{ required: true, validator: skuImageListValidator }]
      }
    }
  },
  computed: {
    ...mapState('category', ['category1Id', 'category2Id', 'category3Id'])
  },
  async mounted() {
    // 获取平台属性，销售属性和Sku图片
    const {
      category1Id,
      category2Id,
      category3Id,
      spu: { spuId }
    } = this
    // promise的allsettled方法，一定返回成功的结果，其中有失败的状态不影响后面的执行
    // 返回值为[{},{}],返回的对象有两种形式
    // 其中{status:"fulfilled",value:{}} 状态为成功，返回值是value
    // {status:"rejected",reason:""} 状态为失败，返回失败的原因
    const [
      attrInfoListResponse,
      spuImageListResponse,
      spuSaleAttrListResponse
    ] = await Promise.allSettled([
      this.$API.attr.reqGetAttrInfoList({
        category1Id,
        category2Id,
        category3Id
      }),
      this.$API.spu.reqGetSpuImageList(spuId),
      this.$API.spu.reqGetSpuSaleAttrList(spuId)
    ])
    // 发送请求后需要根据响应结果的状态分别进行判断
    if (attrInfoListResponse.status === 'fulfilled') {
      this.attrInfoList = attrInfoListResponse.value.data
    } else {
      this.$message({
        type: 'error',
        message: '获取平台属性数据失败'
      })
    }
    if (spuImageListResponse.status === 'fulfilled') {
      // 为每个对象添加响应式的isDefault属性
      this.spuImageList = spuImageListResponse.value.data
      this.spuImageList.forEach(item => {
        this.$set(item, 'isDefault', '0')
      })
    } else {
      this.$message({
        type: 'error',
        message: '获取sku图片数据失败'
      })
    }
    if (spuSaleAttrListResponse.status === 'fulfilled') {
      this.spuSaleAttrList = spuSaleAttrListResponse.value.data
    } else {
      this.$message({
        type: 'error',
        message: '获取销售属性数据失败'
      })
    }
  },
  methods: {
    // 计数器改变时
    handleChange(value) {
      console.log(value)
    },
    // 下拉框列表出现/隐藏时触发，出现的回调为true，隐藏的回调为false
    handleAttrVisibleChange(value) {
      if (value) return
      // validateField方法对部分表单字段进行校验
      this.$refs.sku.validateField('skuAttrValueList')
    },
    handleSaleAttrVisibleChange(value) {
      if (value) return
      this.$refs.sku.validateField('skuSaleAttrValueList')
    },
    // 图片多选框被选中时，默认返回值是选中图片的对象
    handleSelectionChange(val) {
      // el-elment组件内部封装函数，传递的实参是选中的图片组成的新数组
      this.sku.skuImageList = val
    },
    // 设置默认图片
    handleSetDefault(row) {
      // isDefault是响应式的，且多选框添加传递的新数组对象的地址即是vue上代理的spuImageList
      // 数组中对象的地址，因此改变其中的属性isDefault时，传递到sku中的skuImageList的对象下的
      // isDefault也会发生对应的改变
      this.spuImageList.forEach(item => {
        item.isDefault = '0'
      })
      row.isDefault = '1'
      this.$refs.sku.validateField('skuImageList')
    },
    // 确定添加sku
    handleSaveSku() {
      this.$refs.sku.validate(async value => {
        if (value) {
          const {
            category3Id,
            spu: { spuId }
          } = this
          const {
            skuName,
            price,
            weight,
            skuDesc,
            skuAttrValueList,
            skuSaleAttrValueList,
            skuImageList
          } = this.sku
          // 获取默认图片地址
          const skuDefaultImg = skuImageList.find(
            skuImage => skuImage.isDefault === '1'
          ).imgUrl
          await this.$API.sku.reqSaveSkuInfo({
            skuName,
            price,
            weight,
            skuDesc,
            // 处理选中的平台属性
            skuAttrValueList: skuAttrValueList
              .filter(Boolean)
              .map(skuAttrValue => {
                const [
                  attrId,
                  attrName,
                  valueId,
                  valueName
                ] = skuAttrValue.split(':')
                return {
                  attrId,
                  attrName,
                  valueId,
                  valueName
                }
              }),
            // 处理选中的销售属性
            skuSaleAttrValueList: skuSaleAttrValueList
              .filter(Boolean)
              .map(skuSaleAttrValue => {
                const [
                  saleAttrId,
                  saleAttrName,
                  saleAttrValueId,
                  saleAttrValueName
                ] = skuSaleAttrValue.split(':')
                return {
                  saleAttrId,
                  saleAttrName,
                  saleAttrValueId,
                  saleAttrValueName
                }
              }),
            // 处理选中的图片列表
            skuImageList: skuImageList.map(skuImage => {
              return {
                id: skuImage.id,
                imgName: skuImage.imgName,
                imgUrl: skuImage.imgUrl,
                isDefault: skuImage.isDefault
              }
            }),
            category3Id,
            skuDefaultImg,
            spuId
          })
          this.$message({ type: 'success', message: '添加sku完成' })
          this.$emit('isShow', 1)
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.spu-col {
  margin-bottom: 10px;
}
.save-sku-img {
  width: 150px;
  height: 150px;
}
</style>
